package grex.Nodes;

/**
 * <p>Title: </p>
 * <p>Description: </p>
 * <p>Copyright: Copyright (c) 2003</p>
 * <p>Company: </p>
 * @author not attributable
 * @version 1.0
 */
import grex.BNFException;
import grex.ErrorManagement.ErrorManager;
import grex.Options;
import grex.Data.Prediction;
import grex.Data.PredictionContainer;
import java.text.NumberFormat;

public class Var extends Node implements ITerminal,IOperatorTerminal {

    private static final int NROFCILDREN = 0;
    private int conVarNr = -1;
    private int catVarNr = -1;
    private int varNr=-1;
    private int count=0;
    static NumberFormat nf;
    public Var() throws BNFException {
        super(NROFCILDREN);
        if(nf == null){
            nf  = NumberFormat.getInstance();
            nf.setMaximumFractionDigits(3);
        }
    }

    public synchronized void execute(Node parent, PredictionContainer data, int mode) throws GeneException {
        this.parent = parent;
        if(mode==Node.TRAIN_MODE){
            count=data.values().size();
        }
        init();
        for (Prediction p : data.values()) {
            p.setPrediction(p.getInstance()[varNr]);
        //    p.setLeaf(this);
            p.setProb(new Double(0));
        }
    }
    public double getGeneNumericValue(double geneValue){
        return environment.getInternalNumericalValue(varNr, geneValue, getFold());
    }

    public String getGeneRealValue(double geneNumericValue){
        init();
        if(parent instanceof IContinuousOperator)
            return nf.format(geneNumericValue);
        else
            return environment.getRealClassValue(catVarNr,geneNumericValue);
    }

    public void setConVarNr(int conVarNr){
        this.conVarNr = conVarNr;
    }

    public void setVarNr(int varNr) {
        this.varNr = varNr;
    }
    public void setCatVarNr(int varNr) {
        this.catVarNr = varNr;
    }
    public int getVarNr() {
        return varNr;
    }

    public Object clone() {
        Var newVariable;
        try {
            newVariable = new Var();
            newVariable.setVarNr(varNr);
            newVariable.setOptions(ops);
            newVariable.setEnvironment(environment);
            newVariable.setParent(parent);
            newVariable.catVarNr=catVarNr;
            newVariable.conVarNr=conVarNr;
        } catch (grex.BNFException e) {
            ErrorManager.getInstance().reportError(e);
            return null;
        }
        return newVariable;
    }

    public String toString() {

            if (varNr == -1) {
                return "Unused";
            }
            return environment.getVariableNames()[varNr];
    }

    public double getProb() {
        this.getType();
        return 0;
    }

    public double getLowProb() {
        return 0;
    }

    public int getCount() {
        return count;
    }
    public boolean equals(Object o){
        if(o instanceof Var){
            Var v =(Var) o;
            if(varNr==v.getVarNr())
               return true;
        }
        return false;
    }

    private void init() {
        try{
//        if (parent instanceof IContinuousOperator) {
            if (conVarNr == -1 && environment.getNrOfContinuousColumns() > 0) {
                conVarNr = environment.getRandomContiousColumnIndex();
            }
  //          varNr = conVarNr;
  //      } else {
            //Categorisk operator
            if (catVarNr == -1 && environment.getNrOfCategoricalColumns()>0) {
                catVarNr = environment.getRandomCategoricalColumnIndex();
            }
//            varNr = catVarNr;
            if (parent instanceof IContinuousOperator)
                varNr = conVarNr;
            else
                varNr = catVarNr;
        //}
        }catch(GeneException e){
           ErrorManager.getInstance().reportError(e);
           e.printStackTrace();
        }
    }

    public double execute(Node parent, Prediction prediction) {
        this.parent = parent;
         init();
        return prediction.getInstance()[varNr];
    }

}
